package com.css.dzj.dzjap.modules.project.generecord.service.impl;

import com.css.dzj.dzjap.common.util.Constant;
import com.css.dzj.dzjap.common.util.ServiceUtil;
import com.css.dzj.dzjap.common.util.SnowflakeId;
import com.css.dzj.dzjap.modules.info.service.ConstrService;
import com.css.dzj.dzjap.modules.project.generecord.entity.Generecord;
import com.css.dzj.dzjap.modules.project.generecord.entity.QGenerecord;
import com.css.dzj.dzjap.modules.project.generecord.mapper.GenerecordMapper;
import com.css.dzj.dzjap.modules.project.generecord.service.GenerecordService;
import com.css.dzj.dzjap.modules.publick.dao.PublicDao;
import com.css.dzj.dzjap.modules.publick.entity.ApPublicEntity;
import com.css.dzj.dzjap.modules.todolist.entity.ApTodoEntity;
import com.css.dzj.dzjap.modules.todolist.entity.QApTodoEntity;
import com.css.dzj.dzjap.modules.todolist.mapper.ApTodoMapper;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * @author liyuan
 */
@Service
public class GenerecordServiceImpl implements GenerecordService {
    @Autowired
    private GenerecordMapper generecordMapper;
    /**
     * 公开公告Dao
     */
    @Autowired
    private PublicDao publicDao;
    /**
     * 代办已办
     */
    @Autowired
    private ApTodoMapper apTodoMapper;
    @Autowired
    private ConstrService constrService;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private JPAQueryFactory jpaQueryFactory;


    /**
     * 多条件分页查询
     *
     * @param proName
     * @param unitName
     * @param checkStatus
     * @param reCreateDepartment 录入者行政区域
     * @param reCreateUser
     * @param proAddress
     * @param orgLevel
     * @param pageable
     * @return
     */
    @Override
    public QueryResults<Generecord> getPage(String proName, String unitName,
                                            String reCreateUser, String checkStatus,
                                            String reportStatus, String reCreateDepartment,
                                            String proAddress, String orgLevel, Pageable pageable) {
        QGenerecord q = QGenerecord.generecord;
        Predicate predicate = q.isNotNull().or(q.isNull());
        /**
         * 1> 项目地址包含中国时,查找已上报的
         * 2> 项目地址包含建设单位,查找该建设单位下的项目
         * 3> 项目地址不包含中国和建设单位时,查找项目地址
         */
        // 中国地震局
        if (!StringUtils.isEmpty(proAddress) && proAddress.contains("中国")) {
            // 此时若传入上报状态参数,搜查语句不拼接上报状态参数，直接用固定的数值：1
            predicate = ExpressionUtils.and(predicate, q.reportStatus.eq("1"));
        }
        // 建设单位
        if (!StringUtils.isEmpty(proAddress) && proAddress.contains("建设单位")) {
            String unitCode = constrService.findUnitCode(ServiceUtil.getLoginName(request));
            if (StringUtils.isEmpty(unitCode)) {
                throw new RuntimeException("统一信用代码为空");
            }
            // 通过统一信用代码查询
            predicate = ExpressionUtils.and(predicate, q.unitCode.eq(unitCode));
        }
        // 省市地震局
        if (!StringUtils.isEmpty(proAddress) && !proAddress.contains("中国")
                && !proAddress.contains("建设单位")) {
            // 省级：山东省地震局   地市级：山东省-济南市地震局
            predicate = ExpressionUtils.and(predicate, q.proAddress.like("%" + proAddress + "%"));
            // 用户组织等级2：地市级
            if ("2".equals(orgLevel)) {
                // 地市级只能查询地市级的
                predicate = ExpressionUtils.and(predicate, q.orgLevel.eq("2"));
            }
            // 用户组织等级1：省级
            if ("1".equals(orgLevel)) {
                // 省级查询省级所有信息和地市级已提交所有的
                predicate = ExpressionUtils.and(predicate, q.orgLevel.eq("2").and(q.checkStatus.ne("0")));
                predicate = ExpressionUtils.or(predicate, q.orgLevel.eq("1"));
            }
            // 此时若传入上报状态参数,搜查语句拼接上报状态参数，用传入的值：reportStatus
            predicate = (StringUtils.isEmpty(reportStatus)) ? predicate : ExpressionUtils.and(predicate, q.reportStatus.eq(reportStatus));
        }

        // 拼接查询条件：项目名称、单位名称、审核状态、填报部门、填报人员
        predicate = (StringUtils.isEmpty(proName)) ? predicate : ExpressionUtils.and(predicate, q.proName.like("%" + proName + "%"));
        // 建设单位名称-->建设单位不给单位搜索栏，v-if proAddress=="建设单位"判断
        predicate = (StringUtils.isEmpty(unitName)) ? predicate : ExpressionUtils.and(predicate, q.unitName.like("%" + unitName + "%"));
        predicate = (StringUtils.isEmpty(checkStatus)) ? predicate : ExpressionUtils.and(predicate, q.checkStatus.eq(checkStatus));
        predicate = (StringUtils.isEmpty(reCreateDepartment)) ? predicate : ExpressionUtils.and(predicate, q.reCreateDepartment.like("%" + reCreateDepartment + "%"));
        predicate = (StringUtils.isEmpty(reCreateUser)) ? predicate : ExpressionUtils.and(predicate, q.reCreateUser.like("%" + reCreateUser + "%"));
        // 删除标记不为删除
        predicate = ExpressionUtils.and(predicate, q.delFlag.eq(Constant.NO_DELETE));
        // 返回结果
        return jpaQueryFactory
                .selectFrom(q)
                .where(predicate)
                .orderBy(
                        // 根据创建日期，降序排序
                        q.createTime.desc()
                )
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetchResults();
    }

    /**
     * 根据ID查找备案表
     *
     * @param id
     * @return
     */
    @Override
    public Generecord queryById(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        Generecord generecord = generecordMapper.findById(id).get();
        return generecord;
    }

    /**
     * 已办待办任务默认设置接口
     * 说明：新增、暂存==> 待办，审核未过==>已办
     *
     * @param generecord
     */
    private void setApTodo(Generecord generecord) {
        ApTodoEntity todoEntity = new ApTodoEntity();
        // 标题后缀根据审核状态
        String suffix = "";
        if ("0".equals(generecord.getCheckStatus())) {
            suffix = "待提交";
        }
        if ("1".equals(generecord.getCheckStatus())) {
            suffix = "待审定";
        }
        todoEntity.setTitle(generecord.getProName() + suffix);
        todoEntity.setCreateTime(new Date());
        // 只取地址的省地址
        todoEntity.setLocation(generecord.getProAddress().split("-")[0]);
        todoEntity.setDelFlag(Constant.NO_DELETE);
        // 新增方法任务默认1：待办
        todoEntity.setStatus(Constant.STATUSDB);
        todoEntity.setCreatePerson(generecord.getReCreateUser());
        todoEntity.setTypeFlag(Constant.TYPRFLAGSS);
        todoEntity.setUrl("../todolist/general.html");
        todoEntity.setLinkId(generecord.getReId());
        todoEntity.setStation("项目审核员");
        apTodoMapper.save(todoEntity);
    }

    /**
     * 新增
     * 控制层的暂存、提交公用接口方法
     *
     * @param generecord
     */
    @Override
    @Transactional
    public void save(Generecord generecord) {
        if (generecord == null) {
            throw new RuntimeException("备案表为空");
        }
        // 设置默认值,上报状态为0：未上报
        generecord.setReportStatus("0");
        generecord.setDelFlag(Constant.NO_DELETE);
        generecord.setCreateTime(new Date());
        // 拟制公告状态设置默认值0：未拟制
        generecord.setNoticeStatus("0");
        // 前端会自动生成ID带回来，一般不为空
        if (StringUtils.isEmpty(generecord.getReId()))
            generecord.setReId(SnowflakeId.getId());
        /**
         * 新增apTodo待办任务
         * 若是暂存，待办事件新增一条暂存待办---------->暂存取消
         * 若是新增提交，待办事件新增一条提交待办
         */
        if (generecord.getCheckStatus().equals("1"))
            setApTodo(generecord);
        generecordMapper.save(generecord);
    }

    /**
     * 修改 审核状态可以为0：未提交、1：已提交待审核
     *
     * @param generecord
     */
    @Transactional
    @Override
    public void update(Generecord generecord) {
        if (generecord == null) {
            throw new RuntimeException("备案表为空");
        }
        if (StringUtils.isEmpty(generecord.getReId())) {
            throw new RuntimeException("备案表ID为空");
        }
        // 设置更新时间
        generecord.setCreateTime(new Date());
        generecordMapper.save(generecord);
    }

    /**
     * 审核
     *
     * @param generecord
     */
    @Transactional
    @Override
    public void check(Generecord generecord) {
        if (generecord == null) {
            throw new RuntimeException("备案表为空");
        }
        if (StringUtils.isEmpty(generecord.getReId())) {
            throw new RuntimeException("备案表ID为空");
        }
        // 修改审核结果后，同时修改审核状态
        String checkResult = generecord.getCheckResult();
        if (checkResult != null) {
            if ("0".equals(checkResult))
                generecord.setCheckStatus("2");
            else if ("1".equals(checkResult))
                generecord.setCheckStatus("3");
        }
        // 更新创建时间
        generecord.setCreateTime(new Date());
        // 修改apTodo任务状态变成2：已办
        QApTodoEntity q = QApTodoEntity.apTodoEntity;
        jpaQueryFactory.update(q)
                .set(q.status, Constant.STATUSYB)
                .where(q.linkId.eq(generecord.getReId()))
                .execute();
        generecordMapper.save(generecord);
    }

    /**
     * 逻辑删除：根据ID
     *
     * @param id
     */
    @Transactional
    @Override
    public void logicDel(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        QGenerecord q = QGenerecord.generecord;
        jpaQueryFactory.update(q)
                .set(q.delFlag, Constant.DELETE)
                .where(q.reId.eq(id))
                .execute();
    }

    @Override
    @Transactional
    public void updateReportStatus(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        QGenerecord q = QGenerecord.generecord;
        jpaQueryFactory.update(q)
                .set(q.reportStatus, "1")
                .where(q.reId.eq(id))
                .execute();
    }

    /**
     * 更新审核状态为1：已提交待审核
     * 按钮提交不进页面
     *
     * @param id
     */
    @Override
    @Transactional
    public void updateSubmitStatus(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("ID不能为空");
        }
        QGenerecord q = QGenerecord.generecord;
        jpaQueryFactory.update(q)
                .set(q.checkStatus, "1")
                .where(q.reId.eq(id))
                .execute();
        // 变为1：已提交待办后，新增一条待办任务
        Generecord generecord = generecordMapper.findById(id).get();
        setApTodo(generecord);
    }

    /**
     * 一般工程: 添加拟制公告
     *
     * @param apPublicEntity
     */
    @Override
    @Transactional
    public void addPublick(ApPublicEntity apPublicEntity) {
        if (apPublicEntity == null || StringUtils.isEmpty(apPublicEntity.getRelationId())) {
            // RelationId关联表id,即一般工程的ID
            throw new RuntimeException("拟制公告保存失败!");
        }
        /**
         * 添加公告：设置默认值
         */
        if (StringUtils.isEmpty(apPublicEntity.getPublicId())) {
            // 公告主键ID,前端会生成带回，一般不用设置
            apPublicEntity.setPublicId(SnowflakeId.getId());
        }
        apPublicEntity.setRevokeg(Constant.REVOKE_NO);
        apPublicEntity.setDelFlag(Constant.NO_DELETE);
        // base接口工具类获取登录名、组织名称
        apPublicEntity.setCreateUser(ServiceUtil.getLoginName(request));
        apPublicEntity.setOrganName(ServiceUtil.getOrgName(request));
        System.out.println(ServiceUtil.getLoginName(request));
        apPublicEntity.setCreateTime(new Date());
        apPublicEntity.setInputenTime(new Date());
        // 根据此请求路径+RelationId 前端axios获取信息
        apPublicEntity.setPublicUrl("/dzjap/generecord/getInfo");
        // 设置类型3：一般工程，根据此类型前端判断进入哪个页面
        apPublicEntity.setFictionType("3");
        publicDao.save(apPublicEntity);
        /**
         * 拟制公告添加待办已办：调取待办接口
         */
        ApTodoEntity apTodoEntity = new ApTodoEntity();
        apTodoEntity.setStatus(Constant.STATUSDB);
        apTodoEntity.setCreateTime(new Date());
        apTodoEntity.setDelFlag(Constant.NO_DELETE);
        apTodoEntity.setTitle(apPublicEntity.getTitle() + "公开公告审批");
        apTodoEntity.setLinkId(apPublicEntity.getPublicId());
        // 审批员才能看到相应的审批
        apTodoEntity.setStation("地震部门审定人员");
        // 去审批页
        apTodoEntity.setUrl("../todolist/publick.html");
        apTodoEntity.setLocation(apPublicEntity.getOrganName());
        apTodoEntity.setCreatePerson(ServiceUtil.getLoginName(request));
        // 审批的业务
        apTodoEntity.setTypeFlag(Constant.TYPRFLAGSS);
        apTodoMapper.save(apTodoEntity);
        /**
         * 设置拟制公告状态为1：已拟制
         */
        QGenerecord q = QGenerecord.generecord;
        jpaQueryFactory.update(q)
                .set(q.noticeStatus, "1")
                .where(q.reId.eq(apPublicEntity.getRelationId()))
                .execute();
    }

    @Override
    public List<Generecord> getByIn(String location,String industry) {
        QGenerecord q = QGenerecord.generecord;
        List<Generecord> list=null;
       if(!StringUtils.isEmpty(location)&&location.contains(Constant.LOCATIONZG)){
           if(!industry.equals("全部")) {
               list = jpaQueryFactory.selectFrom(q).where(q.delFlag.eq(Constant.NO_DELETE), q.reportStatus.eq(Constant.REPORT_STATUS_YES), q.industry.eq(industry)).fetch();
           }else {
               list=jpaQueryFactory.selectFrom(q).where(q.delFlag.eq(Constant.NO_DELETE),q.reportStatus.eq(Constant.REPORT_STATUS_YES)).fetch();
           }
       }
       if(!StringUtils.isEmpty(location)&&!location.contains(Constant.LOCATIONZG)) {
           if (!industry.equals("全部")) {
               list = jpaQueryFactory.selectFrom(q).where(q.delFlag.eq(Constant.NO_DELETE), q.checkStatus.eq(Constant.CHECK_STATUS3), q.proAddress.like("%" + location + "%"), q.industry.eq(industry)).fetch();
           }else {
               list = jpaQueryFactory.selectFrom(q).where(q.delFlag.eq(Constant.NO_DELETE), q.checkStatus.eq(Constant.CHECK_STATUS3), q.proAddress.like("%" + location + "%")).fetch();
           }
       }
        return list;
    }
}
